<?php
class Membership_model extends Model {
	function Membership_model()
	{
		parent::Model();
	}
	
	// is_* helpers
	public function __call($m, $a)
	{
		if (preg_match('/^is_(.*)/', $m, $matches))
		{
			$CI =& get_instance();
			
			if (!$CI->userland->logged_in())
				return false;
			elseif ($CI->userland->logged_in() && $CI->userland->is_admin())
				return true;
			else
			{
				$user_id   = isset($a[1]) ? $a[1] : $CI->userland->current_user()->id;
				$role_name = ucfirst($matches[1]);
				$box_id    = $a[0];
				$params	   = array($role_name, $box_id, $user_id);
				$query	   = $this->db->query('select roles.id from roles
					where roles.name = ?
						and roles.id <=
							(select memberships.role_id from memberships
								where memberships.bricabox_id = ?
									and memberships.user_id = ? limit 1) limit 1', $params);
				if ($query->num_rows() == 1)
					return true;
			}
		}
	}
		
	public function add_member($bricabox_id, $user_id_or_login)
	{
		$user = $this->_get_user_from_id_or_login($user_id_or_login);
		
		// check if $user is already a member or $user is invalid; if so, return false
		if (!$user || $this->is_member_of($bricabox_id, $user_id_or_login))
		{
			return false;
		}
		else
		{
			$params = array(
				$bricabox_id,
				$user->id
			);
			$this->db->query('insert into memberships (bricabox_id,user_id,role_id,created_at,updated_at)
								values(?,?,3,NOW(),NOW())', $params); // initially add as Member
								
			// log activity
			// record the activity
			$CI =& get_instance();
			$CI->load->model('Activity_model');
			$CI->Activity_model->log_activity(array(
				'action' 		=> 'became a member of',
				'activity_type' => 'joined',
				'object'		=> $bricabox_id,
				'bricabox_id'	=> $bricabox_id,
				'user_id'		=> $user->id,
				'subject'		=> username($this->userland->current_user())
			));					
								
			// TODO send joined email?
			
								
			// also remove a memberapplication if it exists
			$this->db->query('delete from memberapplications where
				user_id = ? and bricabox_id = ?',
				array($user->id, $bricabox_id));
			
			return true;
		}
	}
	
	public function remove_member($bricabox_id, $user_id_or_login)
	{
		$user = $this->_get_user_from_id_or_login($user_id_or_login);
		$params = array(
			$bricabox_id,
			$user->id
		);
		$this->db->query('delete from memberships where bricabox_id = ? and user_id = ?', $params);
		return $user->login; // return the login
	}
	
	public function create_application($bricabox_id, $user_id)
	{
		if (!$this->is_member_of($bricabox_id, $user_id) && !$this->user_applied($bricabox_id, $user_id))
		{
			$this->db->query('insert into memberapplications (user_id,bricabox_id,created_at,updated_at,approved)
				values(?,?,NOW(),NOW(),0)',
				array(
					$user_id,
					$bricabox_id
				));
			return true;
		}
	}
	
	public function user_applied($bricabox_id, $user_id)
	{
		$query = $this->db->query('select * from memberapplications where user_id = ? and bricabox_id = ? limit 1', array($user_id, $bricabox_id));
		if ($query->num_rows() == 1)
			return true;
	}
	
	public function change_role_by_id($bricabox_id, $user_id_or_login, $role_id)
	{
		$user = $this->_get_user_from_id_or_login($user_id_or_login);
		$params = array(
			$role_id,
			$bricabox_id,
			$user->id
		);
		$this->db->query('update memberships set role_id = ? where bricabox_id = ? and user_id = ?', $params);
		return $user->login; // return the login
	}
	
	public function change_role_by_name($bricabox_id, $user_id_or_login, $role_name)
	{
		
	}
	
	// returns true if the given user is a member of the given bricabox
	public function is_member_of($bricabox_id, $user_id_or_login)
	{
		$user = $this->_get_user_from_id_or_login($user_id_or_login);
		if ($user)
		{
			$params = array($bricabox_id, $user->id);
			$query  = $this->db->query('select * from memberships where bricabox_id = ? and user_id = ? limit 1', $params);
			log_message('debug', "[membership] is_member_of $bricabox_id $user_id_or_login");
			if ($query->num_rows() == 1)
				return $query->first_row();
		}
	}
	
	// returns a role record for a given role_id
	public function get_role_for($role_id)
	{
		log_message('debug', "[membership] get_role_for $role_id");
		$query = $this->db->query('select * from roles where id = ? limit 1', array($role_id));
		return $query->first_row();
	}
	
	// returns user records for all members of a bricabox
	public function get_members_of($bricabox_id)
	{
		$query = $this->db->query('select users.* from users
									where users.id in
										(select memberships.user_id from memberships where memberships.bricabox_id = ?)', array($bricabox_id));
		return $query;
	}
	
	public function get_pending($bricabox_id)
	{
		$query = $this->db->query('select users.* from users
									where users.id in
										(select memberapplications.user_id from memberapplications where memberapplications.bricabox_id = ?)', array($bricabox_id));
		return $query;
	}
	
	private function _get_user_from_id_or_login($user_id_or_login)
	{
		log_message('debug', '[membership] _get_user_from_id_or_login '.$user_id_or_login);
		if (!preg_match('/^[0-9]+$/', $user_id_or_login)) // non-numeric
		{
			// login
			$sql = 'select * from users where login = ?';
		}
		else
		{
			// id
			$sql = 'select * from users where id = ?';
		}
		$sql  .= ' limit 1';
		$query = $this->db->query($sql, array($user_id_or_login));
		if ($query->num_rows() == 1)
			return $query->first_row();
	}
}
?>